package ace.cmp.kaptcha.core.service.impl;

import ace.cmp.kaptcha.core.properties.KaptchaProperties;
import ace.cmp.kaptcha.core.service.KaptchaFactory;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import java.awt.*;
import java.lang.reflect.Field;
import java.util.Optional;
import java.util.Properties;
import lombok.SneakyThrows;

/**
 * @author caspar
 * @date 2023/3/21 16:43
 */
public class KaptchaFactoryImpl implements KaptchaFactory {
  @SneakyThrows
  public Optional<String> getColorName(Color color) {
    for (Field f : Color.class.getDeclaredFields()) {
      // we want to test only fields of type Color
      if (f.getType().equals(Color.class) && f.get(null).equals(color)) {
        return Optional.of(f.getName());
      }
    }
    return Optional.empty();
  }

  @Override
  public DefaultKaptcha create(KaptchaProperties properties) {
    Config config = this.getKaptchaConfigFrom(properties);
    DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
    defaultKaptcha.setConfig(config);
    return defaultKaptcha;
  }

  @Override
  public Config getKaptchaConfigFrom(KaptchaProperties properties) {
    Properties prop = this.getKaptchaPropertiesFrom(properties);
    return new Config(prop);
  }

  @Override
  public Properties getKaptchaPropertiesFrom(KaptchaProperties properties) {
    Properties prop = new Properties();

    KaptchaProperties.Border border = properties.getBorder();
    prop.setProperty(Constants.KAPTCHA_BORDER, border.getEnabled() ? "yes" : "no");
    prop.setProperty(
        Constants.KAPTCHA_BORDER_COLOR, this.getColorName(border.getColor()).orElse("BLACK"));
    prop.setProperty(Constants.KAPTCHA_BORDER_THICKNESS, String.valueOf(border.getThickness()));

    KaptchaProperties.Noise noise = properties.getNoise();
    prop.setProperty(Constants.KAPTCHA_NOISE_IMPL, noise.getImpl());
    prop.setProperty(
        Constants.KAPTCHA_NOISE_COLOR, this.getColorName(noise.getColor()).orElse("BLACK"));

    prop.setProperty(
        Constants.KAPTCHA_OBSCURIFICATOR_IMPL, properties.getObscurificatorImpl().getCode());

    prop.setProperty(Constants.KAPTCHA_PRODUCER_IMPL, properties.getProducerImpl());

    prop.setProperty(Constants.KAPTCHA_TEXTPRODUCER_IMPL, properties.getTextProducer().getImpl());
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING,
        properties.getTextProducer().getCharConfig().getSource());
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH,
        String.valueOf(properties.getTextProducer().getCharConfig().getLength()));
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,
        String.valueOf(properties.getTextProducer().getCharConfig().getSpace()));
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES,
        properties.getTextProducer().getFontConfig().getNames());
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE,
        String.valueOf(properties.getTextProducer().getFontConfig().getSize()));
    prop.setProperty(
        Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR,
        this.getColorName(properties.getTextProducer().getFontConfig().getColor()).orElse("BLACK"));

    prop.setProperty(Constants.KAPTCHA_WORDRENDERER_IMPL, properties.getWordImpl());

    prop.setProperty(Constants.KAPTCHA_BACKGROUND_IMPL, properties.getBackground().getImpl());
    prop.setProperty(
        Constants.KAPTCHA_BACKGROUND_CLR_FROM,
        this.getColorName(properties.getBackground().getClear().getFrom()).orElse("LIGHT_GRAY"));
    prop.setProperty(
        Constants.KAPTCHA_BACKGROUND_CLR_TO,
        this.getColorName(properties.getBackground().getClear().getTo()).orElse("WHITE"));

    prop.setProperty(Constants.KAPTCHA_IMAGE_WIDTH, String.valueOf(properties.getWidth()));
    prop.setProperty(Constants.KAPTCHA_IMAGE_HEIGHT, String.valueOf(properties.getHeight()));

    return prop;
  }
}
